package controller

// import (
// 	"bytes"
// 	"container/heap"
// 	"fmt"
// 	"gomvc/app/utils"
// 	"image"
// 	_ "image/png"
// 	"math"
// 	"os"
// 	"strconv"
// 	"sync"

// 	"github.com/gin-gonic/gin"
// )

// var Astar = new(astar)

// type astar struct{}

// var wg sync.WaitGroup

// var mm sync.Mutex

// type Item struct {
// 	X int    `json:"x"`
// 	Y int    `json:"y"`
// 	G int    `json:"g"`
// 	H int    `json:"h"`
// 	P [2]int `json:"p"`
// }

// type Req struct {
// 	Start       [2]int    `json:"start"`
// 	Goal        [2]int    `json:"goal"`
// 	Barrier     [][2]int  `json:"barrier"`
// 	ChangePoint [2][2]int `json:"changePoint"`
// }

// var wmap map[[2]float64]struct{}

// func (*astar) Base(c *gin.Context) {
// 	// 接受参数
// 	var req *Req
// 	c.ShouldBind(&req)
// 	// 存放已检查和待检查，所有可以用，三个通道
// 	// allCh := make(chan Item, 520000)
// 	// openCh := make(chan Item, 520000)
// 	// closeCh := make(chan Item, 520000)
// 	// // 开一个协程往里写所有可以用得像素点
// 	// wg.Add(1)
// 	// go putAll(allCh, req.Barrier)

// 	num := 0

// 	closeList := []Item{}
// 	// openList := []Item{}

// 	openList := &IntHeap{}
// 	heap.Init(openList)
// 	// start := Item{
// 	// 	X: req.Start[0],
// 	// 	Y: req.Start[1],
// 	// 	G: 0,
// 	// 	H: 0,
// 	// 	P: [2]int{-1, -1},
// 	// }
// 	// goal := [2]int{req.Goal[0], req.Goal[1]}
// 	start := Item{
// 		X: 394,
// 		Y: 53,
// 		G: 0,
// 		H: 0,
// 		P: [2]int{-1, -1},
// 	}
// 	goal := [2]int{435, 58}
// 	var dfs func(start Item, openList *IntHeap, closeList []Item)
// 	dfs = func(start Item, openList *IntHeap, closeList []Item) {
// 		num++
// 		// fmt.Println(num)
// 		if (start.X == goal[0] && start.Y == goal[1]) || num == 19999 {
// 			// fmt.Println(closeList)
// 			c.JSON(200, gin.H{
// 				"code": 0,
// 				"msg":  "成功",
// 				"data": gin.H{
// 					"lines":    closeList,
// 					"openList": openList,
// 				},
// 			})
// 			return
// 		}
// 		// time.Sleep(time.Second / 2)
// 		closeList = append(closeList, start)
// 		neiborCh := make(chan [2]int, 9)
// 		go func() {
// 			for i := start.X - 1; i < start.X+2; i++ {
// 				for j := start.Y - 1; j < start.Y+2; j++ {
// 					if i >= 0 && j >= 0 {
// 						if i > req.Barrier[0][0] && i < req.Barrier[1][0] && j > req.Barrier[0][1] && j < req.Barrier[1][1] {
// 							continue
// 						} else {
// 							neiborCh <- [2]int{i, j}
// 						}
// 					}
// 				}
// 			}
// 			close(neiborCh)
// 		}()
// 		for i := 0; i < 8; i++ {
// 			wg.Add(1)
// 			go func() {
// 				for v := range neiborCh {
// 					cItem := Item{
// 						X: v[0],
// 						Y: v[1],
// 						G: getG([2]int{v[0], v[1]}, start),
// 						H: getH([2]int{v[0], v[1]}, goal),
// 						P: [2]int{start.X, start.Y},
// 					}
// 					if !Contain(closeList, cItem) {
// 						// openList = append(openList, cItem)
// 						heap.Push(openList, cItem)
// 					} else {
// 						// closeList = updateG(closeList, cItem, start)
// 						updateG(closeList, cItem, start)
// 					}
// 				}
// 				wg.Done()
// 			}()
// 		}
// 		wg.Wait()
// 		// minItem := getMinF(openList)
// 		minItem := heap.Pop(openList)
// 		// minItem := Item{
// 		// 	X: 394,
// 		// 	Y: 53,
// 		// 	G: 10,
// 		// 	H: 170,
// 		// 	P: [2]int{23, 23},
// 		// }
// 		// openList = removeClose(openList, minItem)
// 		dfs(minItem.(Item), openList, closeList)
// 	}
// 	dfs(start, openList, closeList)
// }

// func (*astar) BaseCh(c *gin.Context) {
// 	var req *Req
// 	c.ShouldBind(&req)
// 	start := [2]int{req.Start[0], req.Start[1]}
// 	goal := [2]int{req.Goal[0], req.Goal[1]}
// 	// fmt.Println(req.Start,start)
// 	wmap = allWhite()
// 	// fmt.Println(wmap)
// 	num := 0
// 	p := map[[2]int][2]int{
// 		{start[0], start[1]}: {start[0], start[1]},
// 	}
// 	g := map[[2]int]int{
// 		{start[0], start[1]}: 0,
// 	}
// 	var syncP sync.Map
// 	var syncG sync.Map
// 	syncP.Store([2]int{start[0], start[1]}, [2]int{start[0], start[1]})
// 	syncG.Store([2]int{start[0], start[1]}, 0)

// 	// closeList := [][3]int{}
// 	openList := &PyHeap{}
// 	heap.Init(openList)
// 	heap.Push(openList, [3]int{0, start[0], start[1]})
// 	for {
// 		num++
// 		minItem := heap.Pop(openList).([3]int)
// 		// closeList = append(closeList, minItem)
// 		if minItem[1] == goal[0] && minItem[2] == goal[1] {
// 			fmt.Println(num)
// 			path := createLine(p, start, goal)
// 			// path := createLineSync(syncP, start, goal)
// 			c.JSON(200, gin.H{
// 				"code": 0,
// 				"msg":  "成功",
// 				"data": gin.H{
// 					"lines":    path,
// 					"openList": openList,
// 				},
// 			})
// 			return
// 		}
// 		for _, s_n := range getNeighbor(minItem) {
// 			// 从s这个已知点产生相邻点的新G值
// 			newCost := g[[2]int{minItem[1], minItem[2]}] + getCost([2]int{minItem[1], minItem[2]}, s_n)
// 			// g没有这个点,赋大值
// 			_, ok := g[s_n]
// 			if !ok {
// 				g[s_n] = math.MaxInt
// 			}
// 			// 更新g并表明父关系
// 			if newCost < g[s_n] {
// 				g[s_n] = newCost
// 				p[s_n] = [2]int{minItem[1], minItem[2]}
// 				heap.Push(openList, [3]int{g[s_n] + getH([2]int{s_n[0], s_n[1]}, [2]int{goal[0], goal[1]}), s_n[0], s_n[1]})
// 				// heap.Push(openList, [3]int{int(gfloat[s_n] + getHFloat(s_n, [2]float64{float64(goal[0]), float64(goal[1])})), int(s_n[0]), int(s_n[1])})
// 				// fmt.Println([3]int{int(gfloat[s_n] + getHFloat(s_n, [2]float64{float64(goal[0]), float64(goal[1])})), int(s_n[0]), int(s_n[1])}, goal)
// 			}
// 		}
// 	}
// }

// // 计算两坐标之间的实际距离

// // 暂时的存白色可形式区域
// func allWhite() map[[2]float64]struct{} {
// 	// 创建一个map
// 	whiteMap := make(map[[2]float64]struct{})
// 	f, err := os.Open("C://Users//王春雨//Desktop//project//gomvc//public//image//HLT.png")
// 	if err != nil {
// 		panic(err)
// 	}
// 	defer f.Close()

// 	img, _, err := image.Decode(f)
// 	if err != nil {
// 		panic(err)
// 	}
// 	// 判断图片像素颜色为白色的点
// 	numwhite := 0
// 	numblack := 0
// 	numelse := 0
// 	// 判断图片像素颜色为黑色的点
// 	for i := 0; i < img.Bounds().Max.X; i++ {
// 		for j := 0; j < img.Bounds().Max.Y; j++ {
// 			r, g, b, _ := img.At(i, j).RGBA()
// 			if r < 50000 && g < 50000 && b < 50000 {
// 				// img转为*RGBA格式
// 				// img := img.(*image.RGBA)
// 				// // 改变该点的颜色为红色
// 				// img.Set(i, j, color.RGBA{255, 0, 0, 255})

// 				numblack++
// 				lng := float64(i)/2 - 180
// 				lat := -float64(j)/2 + 90
// 				whiteMap[[2]float64{lat, lng}] = struct{}{}
// 			} else if r == 65535 && g == 65535 && b == 65535 {
// 				numwhite++
// 			} else {
// 				numelse++
// 			}
// 		}
// 	}
// 	// 保存图片
// 	// out, err := os.Create("C://Users//王春雨//Desktop//project//gomvc//public//image//HLT1.png")
// 	// if err != nil {
// 	// 	panic(err)
// 	// }
// 	// defer out.Close()
// 	// png.Encode(out, img)

// 	return whiteMap
// }
// func Contain(arr []Item, target Item) bool {
// 	for _, eachItem := range arr {
// 		if eachItem.X == target.X && eachItem.Y == target.Y {

// 			return true
// 		}
// 	}
// 	return false
// }

// func Contain1(openCh chan Item, target Item) bool {
// 	for eachItem := range openCh {
// 		if eachItem.X == target.X && eachItem.Y == target.Y {
// 			return true
// 		}
// 	}
// 	return false
// }

// func getH(current, goal [2]int) int {
// 	// return 10 * int(math.Sqrt(math.Pow((float64(current[0])-float64(goal[0])), 2)+math.Pow((float64(current[1])-float64(goal[1])), 2)))
// 	return 10 * int(math.Abs(float64(current[0])-float64(goal[0]))+math.Abs(float64(current[1])-float64(goal[1])))
// }

// func getHFloat(current, goal [2]float64) float64 {
// 	// return 10 * int(math.Sqrt(math.Pow((float64(current[0])-float64(goal[0])), 2)+math.Pow((float64(current[1])-float64(goal[1])), 2)))
// 	// return 10 * (math.Abs(float64(current[0])-float64(goal[0])) + math.Abs(float64(current[1])-float64(goal[1])))
// 	return utils.GetDistance(current[0], current[1], goal[0], goal[1])
// }

// func getG(current [2]int, start Item) int {
// 	if current[0] == start.X || current[1] == start.Y {
// 		return 10 + start.G
// 	}
// 	return 14 + start.G
// }

// func getMinF(openList []Item) Item {
// 	min := math.MaxInt
// 	var minItem Item
// 	for _, item := range openList {
// 		if item.G+item.H < min {
// 			min = item.G + item.H
// 			minItem = item
// 		}
// 	}
// 	return minItem
// }

// func updateG(closeList []Item, cItem, start Item) []Item {
// 	for idx, eachItem := range closeList {
// 		if eachItem.X == cItem.X && eachItem.Y == cItem.Y {
// 			var oG int
// 			if cItem.X == start.X || cItem.Y == start.Y {
// 				oG = 10
// 			} else {
// 				oG = 14
// 			}
// 			if closeList[idx].G > start.G+oG {
// 				closeList[idx].G = start.G + oG
// 			}
// 		}
// 	}
// 	return closeList
// }

// func updateG1(closeCh chan Item, cItem, start Item) {
// 	for eachItem := range closeCh {
// 		if eachItem.X == cItem.X && eachItem.Y == cItem.Y {
// 			var oG int
// 			if cItem.X == start.X || cItem.Y == start.Y {
// 				oG = 10
// 			} else {
// 				oG = 14
// 			}
// 			if eachItem.G > start.G+oG {
// 				// closeList[idx].G = start.G + oG

// 			}
// 		}
// 	}
// }

// func removeClose(openList []Item, start Item) []Item {
// 	ol := []Item{}
// 	for idx, eachItem := range openList {
// 		if eachItem.X == start.X && eachItem.Y == start.Y {
// 			ol = append(openList[:idx], openList[idx+1:]...)
// 			break
// 		}
// 	}
// 	return ol
// }

// func putAll(allCh chan Item, barrier [][2]int) {
// 	wg.Done()
// }

// // ConvertStrSlice2Map 将字符串 slice 转为 map[string]struct{}。
// func ConvertStrSlice2Map(sl []Item) map[string]struct{} {
// 	set := make(map[string]struct{}, len(sl))
// 	for _, v := range sl {
// 		var bt bytes.Buffer
// 		bt.WriteString(strconv.Itoa(v.X))
// 		bt.WriteString(strconv.Itoa(v.Y))
// 		s3 := bt.String()
// 		set[s3] = struct{}{}
// 	}
// 	return set
// }

// // InMap 判断字符串是否在 map 中。
// func InMap(m map[string]struct{}, v Item) bool {
// 	var bt bytes.Buffer
// 	bt.WriteString(strconv.Itoa(v.X))
// 	bt.WriteString(strconv.Itoa(v.Y))
// 	s3 := bt.String()
// 	_, ok := m[s3]
// 	return ok
// }

// type IntHeap []Item

// func (h IntHeap) Len() int      { return len(h) }
// func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }

// //func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] } // 大顶堆
// func (h IntHeap) Less(i, j int) bool {
// 	return h[i].G+h[i].H < h[j].G+h[j].H
// } // 小顶堆

// func (h *IntHeap) Push(x interface{}) {
// 	*h = append(*h, x.(Item))
// }

// func (h *IntHeap) Pop() interface{} {
// 	old := *h
// 	n := len(old)
// 	x := old[n-1]
// 	*h = old[0 : n-1]
// 	return x
// }

// type PyHeap [][3]int

// func (h PyHeap) Len() int      { return len(h) }
// func (h PyHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
// func (h PyHeap) Less(i, j int) bool {
// 	return h[i][0] < h[j][0]
// } // 小顶堆
// func (h *PyHeap) Push(x interface{}) {
// 	*h = append(*h, x.([3]int))
// }
// func (h *PyHeap) Pop() interface{} {
// 	old := *h
// 	n := len(old)
// 	x := old[n-1]
// 	*h = old[0 : n-1]
// 	return x
// }

// func getNeighbor(minItem [3]int) [][2]int {
// 	motions := [8][2]int{
// 		{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1},
// 	}
// 	list := [][2]int{}
// 	for _, u := range motions {
// 		_, is := wmap[[2]float64{float64(minItem[1] + u[0]), float64(minItem[2] + u[1])}]
// 		if !is {
// 			list = append(list, [2]int{minItem[1] + u[0], minItem[2] + u[1]})
// 		}
// 		// if minItem[1]+u[0] > 0 && minItem[2]+u[1] > 0 && !(minItem[1]+u[0] > 400 && minItem[1]+u[0] < 430 && minItem[2]+u[1] > 40 && minItem[2]+u[1] < 540) {
// 		// 	list = append(list, [2]int{minItem[1] + u[0], minItem[2] + u[1]})
// 		// }
// 	}
// 	return list
// }
// func getNeighborCircle(minItem [3]int) [][2]float64 {
// 	step := 0.5
// 	motions := [16][2]float64{
// 		{-step, 0}, {-step * 0.92, step * 0.38}, {-step * 0.71, step * 0.71}, {0, step}, {step * 0.38, step * 0.92}, {step * 0.71, step * 0.71}, {step, 0}, {step * 0.92, -step * 0.38}, {step * 0.71, -step * 0.71}, {step * 0.38, -step * 0.92}, {0, -step}, {-step * 0.38, -step * 0.92}, {-step * 0.71, -step * 0.71}, {-step * 0.92, -step * 0.38}, {-step * 0.71, step * 0.71}, {-step * 0.38, step * 0.92},
// 	}
// 	list := [][2]float64{}
// 	for _, u := range motions {
// 		lat := float64(minItem[1]) + u[1]
// 		lon := float64(minItem[2]) + u[0]
// 		// 保留小数点后一位
// 		lat = math.Floor(lat*10) / 10
// 		lon = math.Floor(lon*10) / 10
// 		_, is := wmap[[2]float64{lat, lon}]
// 		if !is {
// 			list = append(list, [2]float64{lat, lon})
// 		}
// 	}
// 	return list
// }

// func getCost(s, s_n [2]int) int {
// 	// if s[0] == s_n[0] {
// 	// 	// return int(10 * math.Cos(float64(s[0])*math.Pi/180))
// 	// 	return 10
// 	// } else if s[1] == s_n[1] {
// 	// 	// return 10
// 	// 	return int(10 / math.Cos(float64(s[0])*math.Pi/180))
// 	// }
// 	// // 开平方
// 	// // dis := math.Sqrt(math.Pow(10*(math.Cos(float64(s[0]))), 2) + math.Pow(10, 2))
// 	// dis := math.Sqrt(math.Pow(10/math.Cos(float64(s[0])*math.Pi/180), 2) + math.Pow(10, 2))
// 	// return int(dis)

// 	if s[0] == s_n[0] || s[1] == s_n[1] {
// 		return 10
// 	}
// 	return 14
// }

// func getCostCircle(s, s_n [2]float64) int {
// 	if s[0] == s_n[0] || s[1] == s_n[1] {
// 		return 10
// 	}
// 	return 14
// }

// func createLine(p map[[2]int][2]int, start, goal [2]int) [][2]int {
// 	s := [2]int{goal[0], goal[1]}
// 	path := [][2]int{}
// 	bezierPath := []utils.Point{}
// 	for {
// 		s = p[s]
// 		path = append(path, s)
// 		bezierPath = append(bezierPath, utils.Point{X: float64(s[0]), Y: float64(s[1])})
// 		if s[0] == start[0] && s[1] == start[1] {
// 			break
// 		}
// 	}
// 	// utils.DrawBezierCurve(bezierPath)
// 	// return utils.DrawBezierCurve(bezierPath)
// 	return path
// }

// func createLineSync(syncP sync.Map, start, goal [2]int) [][2]int {
// 	s := [2]int{goal[0], goal[1]}
// 	path := [][2]int{}
// 	for {
// 		s1, _ := syncP.Load(s)
// 		s = s1.([2]int)
// 		path = append(path, s)
// 		if s[0] == start[0] && s[1] == start[1] {
// 			break
// 		}
// 	}
// 	return path
// }
